package com.yutel.apk.tool;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

import com.yutel.apk.tool.util.AXMLPrinter;
import com.yutel.apk.tool.util.ApkFilter;
import com.yutel.apk.tool.util.ApkHandler;
import com.yutel.apk.tool.util.ApkInfo;
import com.yutel.apk.tool.util.MD5;

public class ApkTool {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length > 0) {
			File fpath = new File(args[0]);
			if (fpath.isFile()) {
				ApkInfo apkInfo = apk(fpath);
				System.out.printf("%s:[appPackage=%s,md5=%s]\n", apkInfo
						.getFile().getName(), apkInfo.getPackageName(), apkInfo
						.getMd5());
			} else {
				ArrayList<ApkInfo> listAPKInfo = listApk(fpath);
				for (ApkInfo ai : listAPKInfo) {
					System.out.printf("%s:[appPackage=%s,md5=%s]\n", ai
							.getFile().getName(), ai.getPackageName(), ai
							.getMd5());
				}
			}
		} else {
			System.out.println("Usage: java -jar apkinfo.jar <path>");
		}
	}

	public static ApkInfo apk(File file) {
		InputStream stream = getApkInfo(file);
		ApkInfo apkInfo = resolve(stream);
		apkInfo.setFile(file);
		apkInfo.setMd5(MD5.createMd5(file));
		return apkInfo;
	}

	public static ArrayList<ApkInfo> listApk(File strpath) {
		File[] list = getFiles(strpath);
		ArrayList<ApkInfo> listApkInfo = new ArrayList<ApkInfo>();
		if (list != null && list.length > 0) {
			for (File item : list) {
				InputStream stream = getApkInfo(item);
				ApkInfo apkInfo = resolve(stream);
				apkInfo.setFile(item);
				apkInfo.setMd5(MD5.createMd5(item));
				listApkInfo.add(apkInfo);
			}
			list = null;
		}
		return listApkInfo;
	}

	private static ApkInfo resolve(InputStream stream) {
		ApkInfo apkInfo = null;
		try {
			SAXParserFactory parserFactory = SAXParserFactory.newInstance();
			parserFactory.setValidating(false);
			parserFactory.setNamespaceAware(false);
			ApkHandler apkHandler = new ApkHandler();

			String strContent = AXMLPrinter.parse(stream);
			byte[] by = strContent.getBytes("utf-8");
			ByteArrayInputStream bais = new ByteArrayInputStream(by);
			SAXParser parser = parserFactory.newSAXParser();
			parser.parse(bais, apkHandler);
			bais.close();
			parser = null;

			apkInfo = apkHandler.getApkInfo();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return apkInfo;
	}

	private static InputStream getApkInfo(File file) {
		try {
			ZipFile zFile = new ZipFile(file);
			ZipEntry entry = zFile.getEntry("AndroidManifest.xml");
			entry.getComment();
			entry.getCompressedSize();
			entry.getCrc();
			entry.isDirectory();
			entry.getSize();
			entry.getMethod();
			InputStream stream = zFile.getInputStream(entry);
			return stream;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static File[] getFiles(File files) {
		File[] strFiles = null;
		try {
			strFiles = files.listFiles(new ApkFilter());
		} catch (Exception e) {
			e.printStackTrace();
		}
		files = null;
		return strFiles;
	}

}
